#include "Mono10BitDecoder.h"

#define NAME L"Mono10BitDecoder"


Mono10BitDecoder::Mono10BitDecoder()
{
	_name = wstring(NAME);
	_err = wstring(L"NONE");
	_lsb = 0;
}
Mono10BitDecoder::~Mono10BitDecoder()
{
}
bool Mono10BitDecoder::Inited()
{
	return true;
}

void Mono10BitDecoder::Close()
{
	delete this;
}


int Mono10BitDecoder::Decode(unsigned char *dest, int dest_buf_len, unsigned char *source, int color_depth, int column, int line, DecodeRequestStruct* args/* = 0*/)
{
	unsigned char* temp;
	int pixel_num = column * line;
	temp = new unsigned char[pixel_num * 3];
	if (temp == 0)
		return 0;
	memset(temp, 0x00, pixel_num * 3);
	memset(dest, 0x00, dest_buf_len);

	if (color_depth > 8)
	{
		unsigned short* s = (unsigned short*)source;
		
		for (int i = 0; i < pixel_num; i++)
		{
			int nValue = 255 * s[i] / (0x1 << color_depth);
			temp[3 * (pixel_num - i - 1)] = nValue;
			temp[3 * (pixel_num - i - 1) + 1] = nValue;
			temp[3 * (pixel_num - i - 1) + 2] = nValue;
		}
	}
	else
	{
		for (int i = 0; i < pixel_num; i++)
		{
			temp[3 * (pixel_num - i - 1)] = (unsigned char)(source[i]);
			temp[3 * (pixel_num - i - 1) + 1] = (unsigned char)(source[i]);
			temp[3 * (pixel_num - i - 1) + 2] = (unsigned char)(source[i]);
		}
	}

	if (args->UpDownReverse && args->LeftRightReverse == false)
	{
		for (int i = 0; i < line; i++)
		{
			memcpy(dest + i * column * 3, temp + (line - i - 1) * column * 3, column * 3);
		}
	}
	if (args->UpDownReverse == false && args->LeftRightReverse)
	{
		for (int i = 0; i < line; i++)
		{
			for (int j = 0; j < column; j++)
			{
				dest[(column * i + j) * 3 + 0] = temp[(column * i + (column - 1 - j)) * 3 + 0];
				dest[(column * i + j) * 3 + 1] = temp[(column * i + (column - 1 - j)) * 3 + 1];
				dest[(column * i + j) * 3 + 2] = temp[(column * i + (column - 1 - j)) * 3 + 2];
			}
		}
	}
	if (args->UpDownReverse && args->LeftRightReverse)
	{
		for (int i = 0; i < pixel_num; i++){
			dest[(pixel_num - i) * 3 - 1] = temp[i * 3];
			dest[(pixel_num - i) * 3 - 2] = temp[i * 3 + 1];
			dest[(pixel_num - i) * 3 - 3] = temp[i * 3 + 2];
		}
	}
	if (args->UpDownReverse == false && args->LeftRightReverse == false)
	{
		memcpy(dest, temp, column * line * 3);
	}
	delete [] temp;
	return 0;
}

const wchar_t* Mono10BitDecoder::Name()
{
	return _name.c_str();
}
const wchar_t* Mono10BitDecoder::ErrorInfo()
{
	return _err.c_str();
}

void* GetDecoderPlugin(int version)
{
	if (version == DECODER_PLUGIN_INTERFACE_VERSION) {
		return new Mono10BitDecoder();
	}
	else {
		return NULL;
	}
}